package com.xinqi.xinqidev.ws;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.xinqi.xinqidev.bigmodel.gptutils.AuthUrlUtils;
import com.xinqi.xinqidev.bigmodel.secret.PersonalGPTSecret;
import com.xinqi.xinqidev.bigmodel.ws.BigModelNew;
import com.xinqi.xinqidev.config.GetHttpSessionConfig;
import com.xinqi.xinqidev.bigmodel.entity.RoleContent;
import com.xinqi.xinqidev.service.QuestionAnswerLogService;
import com.xinqi.xinqidev.ws.pojo.Message;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.List;

import static com.xinqi.xinqidev.common.BigModelContents.HOST_URL;

/**
 * 监听websocket连接
 */
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
@Component
@Slf4j
public class ChatEndpoint {

    private HttpSession httpSession;

    private String user;//用户名称

    private Session session;//session对象，用来发送远程的请求

    private WebSocket webSocket;

    private BigModelNew gptModel;

    private String mess;

    public List<RoleContent> historyList = new ArrayList<>(); // 对话历史存储集合

    // 个性化参数
    private Long userId;


    @Autowired
    private QuestionAnswerLogService questionAnswerLogService;

    /**
     * 建立websocket连接后，被调用
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        //1，将session进行保存
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        user = (String) this.httpSession.getAttribute("user");
        userId = Long.valueOf((String) this.httpSession.getAttribute("userId")) ;
        log.debug("user is " + user);
        this.session = session;
    }

    /**
     * 浏览器发送消息到服务端，该方法被调用
     * 张三  -->  李四
     *
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {

        if (gptModel != null && !gptModel.getTotalFlag()) {
            log.debug("gpt还未返回全部数据，不可以输入");
            return;
        }


        try {
            //将消息推送给指定的用户
            Message msg = JSON.parseObject(message, Message.class);
            log.debug("msg is " + msg);
            //获取 消息接收方的用户名
            String toName = msg.getToName();
            mess = msg.getMessage();
            //获取消息接收方用户对象的session对象
            getAnswerFromGpt(mess);

        } catch (Exception e) {
            //记录日志
            log.debug("e is " + e);
        }
    }

    //todo
    private void getAnswerFromGpt(String mess) throws Exception {
        OkHttpClient client = new OkHttpClient.Builder().build();
        // 构建鉴权url
        String authUrl = AuthUrlUtils.getAuthUrl(
                HOST_URL,
                PersonalGPTSecret.getApiKey(),
                PersonalGPTSecret.getApiSecret());

        String url = authUrl.toString().
                replace("http://", "ws://").
                replace("https://", "wss://");

        Request request = new Request.Builder().url(url).build();
        gptModel = new BigModelNew(mess, session,historyList,questionAnswerLogService,userId);

        webSocket = client.newWebSocket(request, gptModel);
    }


    /**
     * 断开 websocket 连接时被调用
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        //要不要做点什么？
        System.out.println("关闭了。。。。" + session);

    }

    /**
     * 配置错误信息处理
     *
     * @param session
     * @param t
     */
    @OnError
    public void onError(Session session, Throwable t) {
        //什么都不想打印都去掉就好了
        log.info("【websocket消息】出现未知错误 ");
        //打印错误信息，如果你不想打印错误信息，去掉就好了
        //这里打印的也是  java.io.EOFException: null
        t.printStackTrace();
    }

}
